﻿using Newtonsoft.Json.Serialization;
using System.Reflection;

namespace Service.Framework.Utils
{
    /// <summary>
    /// 属性转换器
    /// </summary>
    public class NullToDefaultPropertyValueProvider : IValueProvider
    {
        private readonly PropertyInfo _memberInfo;
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="memberInfo"></param>
        public NullToDefaultPropertyValueProvider(PropertyInfo memberInfo)
        {
            _memberInfo = memberInfo;
        }

        /// <summary>
        /// 获取Value
        /// </summary>
        /// <param name="target"></param>
        /// <returns></returns>
        public object GetValue(object target)
        {
            var result = _memberInfo.GetValue(target);
            if (_memberInfo.PropertyType == typeof(string) && result == null)
                result = string.Empty;
            return result;
        }

        /// <summary>
        /// 设置Value
        /// </summary>
        /// <param name="target"></param>
        /// <param name="value"></param>
        public void SetValue(object target, object value)
        {
            _memberInfo.SetValue(target, value);
        }
    }

    /// <summary>
    /// 字段转换器
    /// </summary>
    public class NullToDefaultFiledValueProvider : IValueProvider
    {
        private readonly FieldInfo _memberInfo;
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="memberInfo"></param>
        public NullToDefaultFiledValueProvider(FieldInfo memberInfo)
        {
            _memberInfo = memberInfo;
        }

        /// <summary>
        /// 获取Value
        /// </summary>
        /// <param name="target"></param>
        /// <returns></returns>
        public object GetValue(object target)
        {
            var result = _memberInfo.GetValue(target);
            if (_memberInfo.FieldType == typeof(string) && result == null)
                result = string.Empty;
            return result;
        }

        /// <summary>
        /// 设置Value
        /// </summary>
        /// <param name="target"></param>
        /// <param name="value"></param>
        public void SetValue(object target, object value)
        {
            _memberInfo.SetValue(target, value);
        }
    }


    /// <summary>
    /// 字段属性转换器
    /// </summary>
    public class NullToDefaultMemberValueProvider : IValueProvider
    {
        private readonly MemberInfo _memberInfo;
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="memberInfo"></param>
        public NullToDefaultMemberValueProvider(MemberInfo memberInfo)
        {
            _memberInfo = memberInfo;
        }

        /// <summary>
        /// 获取Value
        /// </summary>
        /// <param name="target"></param>
        /// <returns></returns>
        public object GetValue(object target)
        {
            Boolean isField = _memberInfo.MemberType == MemberTypes.Field;
            var result = isField ? ((FieldInfo)_memberInfo).GetValue(target) : ((PropertyInfo)_memberInfo).GetValue(target);
            Type type = isField ? ((FieldInfo)_memberInfo).FieldType : ((PropertyInfo)_memberInfo).PropertyType;
            if (type == typeof(string) && result == null)
                result = string.Empty;
            else if (type == typeof(DateTime?) && result == null)
                result = default(DateTime);
            else if ((type == typeof(Int32?) || type == typeof(Int32)) && (result == null || result.ToString().Equals(string.Empty)))
                result = default(Int32);
            else if ((type == typeof(Int16?) || type == typeof(Int16)) && (result == null || result.ToString().Equals(string.Empty)))
                result = default(Int16);
            else if ((type == typeof(Byte?) || type == typeof(Byte)) && (result == null || result.ToString().Equals(string.Empty)))
                result = default(Byte);
            return result;
        }

        /// <summary>
        /// 设置Value
        /// </summary>
        /// <param name="target"></param>
        /// <param name="value"></param>
        public void SetValue(object target, object value)
        {
            if (_memberInfo.MemberType == MemberTypes.Property)
            {
                ((PropertyInfo)_memberInfo).SetValue(target, value);
            }
            else
            {
                ((FieldInfo)_memberInfo).SetValue(target, value);
            }
        }
    }

}
